package com.probox.common.entity.service.platfom.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.probox.activity.api.domain.ActivityCouponVo;
import com.probox.activity.api.domain.ActivityInfoVo;
import com.probox.common.core.enums.ActivityStatusEnum;
import com.probox.common.core.enums.ActivityTypeEnum;
import com.probox.common.core.enums.ComponentDataType;
import com.probox.common.core.enums.DataStatus;
import com.probox.common.core.exception.PlatformException;
import com.probox.common.core.utils.DateUtils;
import com.probox.common.core.utils.SecurityUtils;
import com.probox.common.core.utils.StringUtils;
import com.probox.common.core.utils.money.MoneyUtils;
import com.probox.common.entity.domain.platfom.PlatformCms;
import com.probox.common.entity.domain.platfom.PlatformPageConfigData;
import com.probox.common.entity.domain.platfom.PlatformStore;
import com.probox.common.entity.domain.platfom.vo.UseTypeVo;
import com.probox.common.entity.domain.platfom.vo.api.PlatformComponentDataVo;
import com.probox.common.entity.domain.platfom.vo.api.PlatformComponentVo;
import com.probox.common.entity.domain.platfom.vo.api.PlatformPageVo;
import com.probox.common.entity.domain.platfom.vo.api.PlatformTemplateView;
import com.probox.common.entity.domain.product.vo.ProductBuyersshowQuery;
import com.probox.common.entity.domain.product.vo.ProductInfoQuery;
import com.probox.common.entity.mapper.platfom.PlatformPageConfigDataMapper;
import com.probox.common.entity.service.platfom.IPlatformCmsService;
import com.probox.common.entity.service.platfom.IPlatformPageConfigComponentService;
import com.probox.common.entity.service.platfom.IPlatformPageConfigDataService;
import com.probox.common.entity.service.platfom.IPlatformStoreService;
import com.probox.common.entity.service.product.IProductBuyersshowService;
import com.probox.common.entity.service.product.IProductGroupService;
import com.probox.common.entity.service.product.IProductInfoService;
import com.probox.common.entity.service.wechat.IWchatBroadcastService;
import com.probox.platform.api.domain.PlatformStoreVo;
import com.probox.product.api.domain.ProductBuyersshowVo;
import com.probox.product.api.domain.ProductGroupViewVo;
import com.probox.product.api.domain.ProductInfoVo;
import com.probox.wechat.api.domain.WechatBroadcastVo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;

import static com.probox.common.core.utils.bean.BeanUtils.beanToMap;

/**
 * 页面组件数据信息Service业务层处理
 *
 * @date 2021-06-10
 */
@Service
@Transactional
public class PlatformPageConfigDataServiceImpl extends ServiceImpl<PlatformPageConfigDataMapper, PlatformPageConfigData> implements IPlatformPageConfigDataService {
    @Autowired
    private PlatformPageConfigDataMapper platformPageConfigDataMapper;

    @Autowired
    private IPlatformCmsService iPlatformCmsService;

    @Autowired
    private IPlatformPageConfigComponentService iPlatformPageConfigComponentService;

    @Autowired
    private IWchatBroadcastService wchatBroadcastService;

    @Autowired
    private IPlatformStoreService iPlatformStoreService;

    @Autowired
    private IProductInfoService iProductInfoService;

    @Autowired
    private IProductGroupService iProductGroupService;

    @Autowired
    private IProductBuyersshowService iProductBuyersshowService;

    private static final String API = "1";//用于前端使用获取模板数据

    private static final String CONSOLE = "0";//用于后盾获取模板数据

    /**
     * 查询页面组件数据信息
     *
     * @param dataUid 页面组件数据信息ID
     * @return 页面组件数据信息
     */
    @Override
    public PlatformPageConfigData selectPlatformPageConfigDataById(Long dataUid) {
        return this.getById(dataUid);
    }

    /**
     * 查询页面组件数据信息列表
     *
     * @param platformPageConfigData 页面组件数据信息
     * @return 页面组件数据信息
     */
    @Override
    public List<PlatformPageConfigData> queryList(PlatformPageConfigData platformPageConfigData) {
        QueryWrapper<PlatformPageConfigData> queryWrapper = Wrappers.query();
        if (StringUtils.isNotEmpty(String.valueOf(platformPageConfigData.getComponentUid())) && platformPageConfigData.getComponentUid() != null) {
            queryWrapper.eq("COMPONENT_UID", platformPageConfigData.getComponentUid());
        }

        if (StringUtils.isNotEmpty(String.valueOf(platformPageConfigData.getDataStatus())) && platformPageConfigData.getDataStatus() != null) {
            queryWrapper.eq("DATA_STATUS", platformPageConfigData.getDataStatus());
        }
        queryWrapper.orderByAsc("DATA_SORT");
        return platformPageConfigDataMapper.selectList(queryWrapper);
    }

    /**
     * 添加组件数据信息
     *
     * @param platformTemplateView 模板信息vo
     * @param voComponet           模板组件信息vo
     */
    @Override
    public void insertPlatformPageConfigData(PlatformTemplateView platformTemplateView, PlatformComponentVo voComponet) {
        List<PlatformComponentDataVo> data = voComponet.getData();
        //if (ObjectUtil.isEmpty(data)) throw new PlatformException("组件数据信息错误");
        if (ObjectUtil.isNotEmpty(data)) {
            data.forEach(vo -> {
                saveData(platformTemplateView, voComponet, vo, null);
            });
        }
    }

    /**
     * 复制组件信息数据
     *
     * @param view
     * @param componentUid
     */
    @Override
    public void copyPlatformPageConfigData(PlatformTemplateView view, String componentUid, String copyComponentUid) {
        PlatformPageConfigData platformPageConfigData = new PlatformPageConfigData();
        platformPageConfigData.setDataStatus(DataStatus.valid.getKey());
        platformPageConfigData.setComponentUid(componentUid);
        List<PlatformPageConfigData> platformPageConfigDatas = this.queryList(platformPageConfigData);
        if (ObjectUtil.isNotEmpty(platformPageConfigDatas)) {
            platformPageConfigDatas.forEach(data -> {
                data.setComponentUid(copyComponentUid);
                saveDataCopy(view, data);
            });
        }

    }

    /**
     * 页面获得数据
     *
     * @param vo
     * @param uid
     * @return
     */
    @Override
    public PlatformPageVo getDataVoForVO(PlatformPageVo vo, Long uid) {
        List<PlatformComponentVo> platformPageConfigComponents = vo.getComponent();
        UseTypeVo useTypeVo = new UseTypeVo(null, "1");
        List<PlatformComponentVo> list = new ArrayList<>();
        if (ObjectUtil.isNotEmpty(platformPageConfigComponents)) {
            platformPageConfigComponents.forEach(component -> {
                component.setData(this.getDataVo(component.getComponentUid(), component.getLimitsNumber(), uid, useTypeVo, null));
                list.add(component);
            });
            vo.setComponent(list);
        }
        return vo;
    }

    /**
     * 获取组件数据信息
     *
     * @param componentUid
     * @param limitsNumber
     * @return
     */
    @Override
    public List<PlatformComponentDataVo> getDataVo(String componentUid, Integer limitsNumber, Long uid, UseTypeVo useTypeVo, String sourceComponentUid) {
        PlatformPageConfigData platformPageConfigData = new PlatformPageConfigData();
        platformPageConfigData.setDataStatus(DataStatus.valid.getKey());
        platformPageConfigData.setComponentUid(componentUid);
        List<PlatformPageConfigData> platformPageConfigDatas = this.queryList(platformPageConfigData);
        List<PlatformComponentDataVo> list = new ArrayList<>();
        if (ObjectUtil.isNotEmpty(platformPageConfigDatas)) {
            list = getList(list, platformPageConfigDatas, uid, limitsNumber, API);
        } else {
            //能否获取组件数据的判断
            if (ObjectUtil.isNotEmpty(useTypeVo)) {
                if (CONSOLE.equals(useTypeVo.getUseType()) && ObjectUtil.isNotEmpty(useTypeVo.getTemplateUid())) {
                    //校验成功获取模板的相关数据
                    if (ObjectUtil.isNotEmpty(sourceComponentUid)) {
                        platformPageConfigData = new PlatformPageConfigData();
                        platformPageConfigData.setComponentUid(sourceComponentUid);
                        List<PlatformPageConfigData> platformPageConfigDataList = this.queryList(platformPageConfigData);
                        list = getList(list, platformPageConfigDataList, 1L, limitsNumber, CONSOLE);
                    }
                }
            }
        }
        return list;
    }

    private List<PlatformComponentDataVo> getList(List<PlatformComponentDataVo> list, List<PlatformPageConfigData> platformPageConfigDatas, Long uid, Integer limitsNumber, String type) {
        for (int i = 0; i < platformPageConfigDatas.size(); i++) {
            PlatformPageConfigData data = platformPageConfigDatas.get(i);
            if (ComponentDataType.activity.getKey().equals(data.getDataType()) || ComponentDataType.groupProduct.getKey().equals(data.getDataType())) {//自己的个数限制
                if (ObjectUtil.isNotEmpty(data.getLimitsNumber()) && data.getLimitsNumber() > 0) {
                    if (data.getLimitsNumber() >= i) {
                        PlatformComponentDataVo componentDataVo = new PlatformComponentDataVo();
                        BeanUtils.copyProperties(data, componentDataVo);
                        componentDataVo = set(componentDataVo, uid); // 如果null立即停止循环并且返回null,交给组件那里进行判断
                        if (ObjectUtil.isEmpty(componentDataVo)) continue;
                        if (CONSOLE.equals(type)) {
                            componentDataVo.setDataUid(null);
                            componentDataVo.setDataLink("");
                        }
                        list.add(componentDataVo);
                    }
                } else {
                    PlatformComponentDataVo componentDataVo = new PlatformComponentDataVo();
                    BeanUtils.copyProperties(data, componentDataVo);
                    componentDataVo = set(componentDataVo, uid); // 如果null立即停止循环并且返回null,交给组件那里进行判断
                    if (ObjectUtil.isEmpty(componentDataVo)) continue;
                    if (CONSOLE.equals(type)) {
                        componentDataVo.setDataUid(null);
                        componentDataVo.setDataLink("");
                    }
                    list.add(componentDataVo);
                }
            } else {
                if (ObjectUtil.isNotEmpty(limitsNumber) && limitsNumber > 0) { // 组件的个数限制
                    if (limitsNumber >= i) {
                        PlatformComponentDataVo componentDataVo = new PlatformComponentDataVo();
                        BeanUtils.copyProperties(data, componentDataVo);
                        componentDataVo = set(componentDataVo, uid); // 如果null立即停止循环并且返回null,交给组件那里进行判断
                        if (ObjectUtil.isEmpty(componentDataVo)) continue;
                        if (CONSOLE.equals(type)) {
                            componentDataVo.setDataUid(null);
                            componentDataVo.setDataLink("");
                        }
                        list.add(componentDataVo);
                    }
                } else {
                    PlatformComponentDataVo componentDataVo = new PlatformComponentDataVo();
                    BeanUtils.copyProperties(data, componentDataVo);
                    componentDataVo = set(componentDataVo, uid); // 如果null立即停止循环并且返回null,交给组件那里进行判断
                    if (ObjectUtil.isEmpty(componentDataVo)) continue;
                    if (CONSOLE.equals(type)) {
                        componentDataVo.setDataUid(null);
                        componentDataVo.setDataLink("");
                    }
                    list.add(componentDataVo);
                }
            }
        }
        return list;
    }

    private PlatformComponentDataVo set(PlatformComponentDataVo componentDataVo, Long uid) {

        if (ComponentDataType.notic.getKey().equals(componentDataVo.getDataType())) {
            PlatformCms data = iPlatformCmsService.getData(componentDataVo.getBusinessUid(), uid);
            if (ObjectUtil.isEmpty(data)) return null;
            componentDataVo.setDataVo(beanToMap(data));
            return componentDataVo;
        }

        if (ComponentDataType.groupProduct.getKey().equals(componentDataVo.getDataType())) {
            ProductGroupViewVo groupVo = iProductGroupService.getGroupVo(componentDataVo.getBusinessUid());
            if (ObjectUtil.isEmpty(groupVo)) return null;
            componentDataVo.setDataVo(beanToMap(groupVo));
            return componentDataVo;
        }
        if (ComponentDataType.img.getKey().equals(componentDataVo.getDataType())) {
            componentDataVo.setDataVo(null);
            return componentDataVo;
        }

        if (ComponentDataType.video.getKey().equals(componentDataVo.getDataType())) {
            componentDataVo.setDataVo(null);
            return componentDataVo;
        }
        if (ComponentDataType.live.getKey().equals(componentDataVo.getDataType())) {
            WechatBroadcastVo broadcastById = wchatBroadcastService.getBroadcastById(componentDataVo.getBusinessUid(), uid);
            if (ObjectUtil.isEmpty(broadcastById)) return null;
            componentDataVo.setDataVo(beanToMap(broadcastById));
            return componentDataVo;
        }
        if (ComponentDataType.luckDraw.getKey().equals(componentDataVo.getDataType())) {
            componentDataVo.setDataVo(null);
            return componentDataVo;
        }
        if (ComponentDataType.store.getKey().equals(componentDataVo.getDataType())) {
            PlatformStoreVo vo = iPlatformStoreService.getVo(new PlatformStore(componentDataVo.getBusinessUid(), uid));
            if (ObjectUtil.isEmpty(vo)) return null;
            componentDataVo.setDataVo(beanToMap(vo));
            return componentDataVo;
        }
        if (ComponentDataType.information.getKey().equals(componentDataVo.getDataType())) {
            componentDataVo.setDataVo(null);
            PlatformCms data = iPlatformCmsService.getData(componentDataVo.getBusinessUid(), uid);
            if (ObjectUtil.isEmpty(data)) return null;
            if (ObjectUtil.isNotEmpty(data)) {
                Date publishTime = data.getPublishTime();
                HashMap<String, Object> stringObjectHashMap = beanToMap(data);
                stringObjectHashMap.put("publishTime", DateUtils.formate(publishTime));
                componentDataVo.setDataVo(stringObjectHashMap);
            }
            return componentDataVo;
        }

        if (ComponentDataType.buyersshow.getKey().equals(componentDataVo.getDataType())) {
            ProductBuyersshowQuery query = new ProductBuyersshowQuery();
            query.setBuyersshowUid(componentDataVo.getBusinessUid());
            ProductBuyersshowVo productBuyersshowVo = iProductBuyersshowService.get(query);
            if (ObjectUtil.isEmpty(productBuyersshowVo)) return null;
            componentDataVo.setDataVo(beanToMap(productBuyersshowVo));
            return componentDataVo;
        }

        return componentDataVo;
    }


    /**
     * 修改组件数据信息
     *
     * @param platformTemplateView
     * @param voComponet
     */
    @Override
    public void updatePlatformPageConfigData(PlatformTemplateView platformTemplateView, PlatformComponentVo voComponet) {
        List<PlatformComponentDataVo> data = voComponet.getData();
        removeData(voComponet.getComponentUid());
        //if (ObjectUtil.isEmpty(data)) throw new PlatformException("组件数据信息错误");
        if (ObjectUtil.isNotEmpty(data)) {
            data.forEach(vo -> {
                if (ObjectUtil.isEmpty(vo.getDataUid())) {
                    saveData(platformTemplateView, voComponet, vo, null);
                } else {
                    editData(platformTemplateView, voComponet, vo);
                }
            });
        }
    }

    /**
     * 批量删除页面组件数据信息
     *
     * @param dataUids 需要删除的页面组件数据信息ID
     * @return 结果
     */
    @Override
    public boolean deletePlatformPageConfigDataByIds(Long[] dataUids) {
        return this.removeByIds(Arrays.asList(dataUids));
    }

    public void removeData(String componentUid) {
        UpdateWrapper<PlatformPageConfigData> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("COMPONENT_UID", componentUid);
        updateWrapper.set("DATA_STATUS", DataStatus.delete.getKey());
        updateWrapper.set("UPDATE_UID", SecurityUtils.getUserId());
        updateWrapper.set("UPDATE_NAME", SecurityUtils.getUsername());
        updateWrapper.set("UPDATE_TIME", DateUtil.date());
        this.update(updateWrapper);
    }

    /**
     * @param view
     * @param voComponet
     * @param vo
     */
    private void saveData(PlatformTemplateView view, PlatformComponentVo voComponet, PlatformComponentDataVo vo, PlatformPageConfigData data) {
        PlatformPageConfigData configData = new PlatformPageConfigData();
        if (ObjectUtil.isEmpty(data)) {
            BeanUtils.copyProperties(vo, configData);
            configData.setComponentUid(voComponet.getComponentUid());
        } else {
            BeanUtils.copyProperties(data, configData);
            //configData.setComponentUid(voComponet.getComponentUid());
        }
        if (ObjectUtil.isEmpty(configData.getDataLink())) {
            configData.setDataLink("");
        }
        checkData(configData, view.getUserId(), view.getPlatformUid());// 校验数据
        configData.setCreateName(view.getUserName());
        configData.setCreateUid(view.getUserId());
        configData.setCreateTime(view.getTime());
        configData.setUpdateName(view.getUserName());
        configData.setUpdateUid(view.getUserId());
        configData.setUpdateTime(view.getTime());
        configData.setDataStatus(DataStatus.valid.getKey());

        boolean save = this.save(configData);
        if (!save) throw new PlatformException("添加组件数据信息错误,请稍后再试！");
    }

    private void saveDataCopy(PlatformTemplateView view, PlatformPageConfigData data) {
        PlatformPageConfigData configData = new PlatformPageConfigData();
        BeanUtils.copyProperties(data, configData);
        if (ObjectUtil.isEmpty(configData.getDataLink())) {
            configData.setDataLink("");
        }
        checkData(configData, view.getUserId(), view.getPlatformUid());// 校验数据
        configData.setCreateName(view.getUserName());
        configData.setCreateUid(view.getUserId());
        configData.setCreateTime(view.getTime());
        configData.setUpdateName(view.getUserName());
        configData.setUpdateUid(view.getUserId());
        configData.setUpdateTime(view.getTime());
        configData.setDataStatus(DataStatus.valid.getKey());
        boolean save = this.save(configData);
        if (!save) throw new PlatformException("添加组件数据信息错误,请稍后再试！");
    }

    private void editData(PlatformTemplateView view, PlatformComponentVo voComponet, PlatformComponentDataVo vo) {
        PlatformPageConfigData configData = new PlatformPageConfigData();
        BeanUtils.copyProperties(vo, configData);
        if (ObjectUtil.isEmpty(vo.getDataLink())) configData.setDataLink("");
        checkData(configData, view.getUserId(), view.getPlatformUid());// 校验数据
        configData.setComponentUid(voComponet.getComponentUid());
        configData.setUpdateName(view.getUserName());
        configData.setUpdateUid(view.getUserId());
        configData.setUpdateTime(view.getTime());
        configData.setDataStatus(DataStatus.valid.getKey());
        this.updateById(configData);

    }

    /**
     * 校验数据
     *
     * @param configData
     * @param userUid
     * @param uid
     */
    private void checkData(PlatformPageConfigData configData, Long userUid, Long uid) {
        if (!SecurityUtils.isAdmin(userUid)) {//不是管理员才校验数据
            if (ComponentDataType.good.getKey().equals(configData.getDataType())) {
                if (ObjectUtil.isEmpty(configData.getBusinessUid())) throw new PlatformException("请添加商品数据！");
                ProductInfoVo data = iProductInfoService.getProductDetail(configData.getBusinessUid());
                if (ObjectUtil.isEmpty(data))
                    throw new PlatformException("商品组件中,有已被下架或者是删除了的商品信息又或者是存在模板商品！");
                if (ObjectUtil.isEmpty(data.getPlatformUid()))
                    throw new PlatformException("商品组件中,有已被下架或者是删除了的商品信息又或者是存在模板商品!");
                if (!uid.equals(data.getPlatformUid())) throw new PlatformException("商品组件中有模板商品,请替换成您的商品！");
            }
            if (ComponentDataType.notic.getKey().equals(configData.getDataType())) {
                if (ObjectUtil.isEmpty(configData.getBusinessUid())) throw new PlatformException("请添加公告数据！");
                PlatformCms data = iPlatformCmsService.getData(configData.getBusinessUid(), uid);
                if (ObjectUtil.isEmpty(data)) throw new PlatformException("公告组件中,有已被下架或者是删除了的公告信息又或者是存在模板公告！");
                if (ObjectUtil.isEmpty(data.getPlatformUid()))
                    throw new PlatformException("公告组件中,有已被下架或者是删除了的公告信息又或者是存在模板公告！");
                if (!uid.equals(data.getPlatformUid())) throw new PlatformException("公告组件中有模板公告,请替换成您的公告！");
            }
            if (ComponentDataType.information.getKey().equals(configData.getDataType())) {
                if (ObjectUtil.isEmpty(configData.getBusinessUid())) throw new PlatformException("请添加资讯数据！");
                PlatformCms data = iPlatformCmsService.getData(configData.getBusinessUid(), uid);
                if (ObjectUtil.isEmpty(data)) throw new PlatformException("资讯组件中,有已被下架或者是删除了的资讯信息又或者是存在模板资讯！");
                if (ObjectUtil.isEmpty(data.getPlatformUid()))
                    throw new PlatformException("资讯组件中,有已被下架或者是删除了的资讯信息又或者是存在模板资讯！");
                if (!uid.equals(data.getPlatformUid())) throw new PlatformException("资讯组件中有模板资讯,请替换成您的资讯！");
            }
            if (ComponentDataType.store.getKey().equals(configData.getDataType())) {
                if (ObjectUtil.isEmpty(configData.getBusinessUid())) throw new PlatformException("请添加门店数据！");
                PlatformStoreVo data = iPlatformStoreService.getVo(new PlatformStore(configData.getBusinessUid(), Long.valueOf(uid)));
                if (ObjectUtil.isEmpty(data)) throw new PlatformException("门店组件中,有已被下架或者是删除了的门店信息又或者是存在模板门店！");
                if (ObjectUtil.isEmpty(data.getPlatformUid()))
                    throw new PlatformException("门店组件中,有已被下架或者是删除了的门店信息又或者是存在模板门店！");
                if (!uid.equals(data.getPlatformUid())) throw new PlatformException("门店组件中有模板门店,请替换成您的门店！");
            }


            if (ComponentDataType.groupProduct.getKey().equals(configData.getDataType())) {
                if (ObjectUtil.isEmpty(configData.getBusinessUid())) throw new PlatformException("请添加商品数据！");
                ProductGroupViewVo groupVo = iProductGroupService.getGroupVo(configData.getBusinessUid());

                if (ObjectUtil.isEmpty(groupVo))
                    throw new PlatformException("商品组件中,有已被下架或者是删除了的商品信息又或者是存在模板商品！");
                if (ObjectUtil.isEmpty(groupVo.getPlatformUid()))
                    throw new PlatformException("商品组件中,有已被下架或者是删除了的商品信息又或者是存在模板商品！");
                if (!uid.equals(groupVo.getPlatformUid())) throw new PlatformException("商品组件中有模板商品,请替换成您的商品！");
            }

            if (ComponentDataType.live.getKey().equals(configData.getDataType())) {
                if (ObjectUtil.isEmpty(configData.getBusinessUid())) throw new PlatformException("请添加直播数据！");
                WechatBroadcastVo broadcastById = wchatBroadcastService.getBroadcastById(configData.getBusinessUid(), Long.valueOf(uid));
                if (ObjectUtil.isEmpty(broadcastById))
                    throw new PlatformException("直播组件中,有已被下架或者是删除了的直播信息又或者是存在模板直播！");
                if (ObjectUtil.isEmpty(broadcastById.getPlatformUid()))
                    throw new PlatformException("直播组件中,有已被下架或者是删除了的直播信息又或者是存在模板直播！");
                if (!uid.equals(broadcastById.getPlatformUid()))
                    throw new PlatformException("直播组件中有模板直播,请替换成您的直播！");
            }
        }
    }

}
